﻿using System;
using System.Collections.Generic;
using System.Text;
using SimpleLinearAlgebra;

namespace BarStructures.Analysers
{
    public static class ElementXYHelper
    {
        public static ISimpleMatrix BarTransformationMatrix(Bar bar, bool transposed)
        {
            double[][] tm = new double[4][];
            double c = bar.Cos;
            double s = bar.Sin;
            if (!transposed)
            {
                tm[0] = new double[4] { c, -s, 0, 0 };
                tm[1] = new double[4] { s, c, 0, 0 };
                tm[2] = new double[4] { 0, 0, c, -s };
                tm[3] = new double[4] { 0, 0, s, c };
            }
            else
            {
                tm[0] = new double[4] { c, s, 0, 0 };
                tm[1] = new double[4] { -s, c, 0, 0 };
                tm[2] = new double[4] { 0, 0, c, s };
                tm[3] = new double[4] { 0, 0, -s, c };
            }
            return new SimpleMatrix(tm);
        }

        public static ISimpleMatrix BarGlobalStiffnessMatrix(Bar bar)
        {
            ISimpleMatrix result;

            result = MxOp.Product(BarTransformationMatrix(bar, false), BarLocalStiffnessMatrix(bar));
            result = MxOp.Product(result, BarTransformationMatrix(bar, true));

            return result;
        }

        public static ISimpleMatrix BarLocalStiffnessMatrix(Bar bar)
        {
            double[][] lsm = new double[4][];
            double ea = bar.Phys.E * bar.Phys.A / bar.Length;

            lsm[0] = new double[4] { ea, 0, -ea, 0 };
            lsm[1] = new double[4] { 0, 0, 0, 0 };
            lsm[2] = new double[4] { -ea, 0, ea, 0 };
            lsm[3] = new double[4] { 0, 0, 0, 0 };
            return new SimpleMatrix(lsm);
        }

        public static ISimpleMatrix BarDescreeteMassMatrix(Bar bar)
        {
            double m = 0.1 * bar.Phys.Density * bar.Length * bar.Phys.A / 2;
            ISimpleMatrix mx = new SimpleMatrix(4, 4);
            mx.SetElement(0, 0, m);
            mx.SetElement(1, 1, m);
            mx.SetElement(2, 2, m);
            mx.SetElement(3, 3, m);
            mx = MxOp.Product(BarTransformationMatrix(bar, false), mx);
            mx = MxOp.Product(mx, BarTransformationMatrix(bar, true));
            return mx;
        }

        public static ISimpleMatrix BarConsistentMassMatrix(Bar bar)
        {
            double l = bar.Length;
            double l2 = l * l;
            double k = 0.1 * bar.Phys.Density * bar.Phys.A * l / 420;
            double[][] lmm = new double[4][];
            lmm[0] = new double[4] { 156, 22 * l, 54, -13 * l };
            lmm[1] = new double[4] { 22 * l, 4 * l2, 13 * l, -3 * l2 };
            lmm[2] = new double[4] { 54, 13 * l, 156, -22 * l };
            lmm[3] = new double[4] { -13 * l, -3 * l2, -22 * l, 4 * l2 };

            ISimpleMatrix mx = new SimpleMatrix(lmm);
            mx = MxOp.Product(BarTransformationMatrix(bar, false), mx);
            mx = MxOp.Product(mx, BarTransformationMatrix(bar, true));
            return mx;
        }
    }
}
